<template>
    <div class="Box" ref="Box" @wheel="Wheel" @mousedown="Move">
        <div
            class="Board"
            ref="Board"
            :style="{
                width: `${width}px`,
                height: `${height}px`,
                transform: `translate(${MoveCache.x}px,${MoveCache.y}px) scale(${MoveCache.scale})`,
            }"
            @mouseup="AddEvent"
        >
            <slot :scale="MoveCache.scale" :MoveEvent="Move"></slot>
            <LinkCanvas ref="LinkCanvasView" :scale="MoveCache.scale" :width="width" :height="height" />
        </div>
        <div class="Status">
            <span class="Zoom">
                {{ parseFloat(MoveCache.scale * 100).toFixed(0) }}% <fullscreen-outlined class="fullscreen" @click="fullscreen"
            /></span>
        </div>
    </div>
    <a-modal
        v-model:visible="AddeventVisible"
        title="配置参数"
        @ok="
            AddEventCache(AddObject);
            AddeventVisible = false;
        "
    >
        <a-form>
            <a-form-item label="Key">
                <a-input v-model:value="AddObject.key"></a-input>
            </a-form-item>
            <a-form-item label="Type">
                <a-input v-model:value="AddObject.type"></a-input>
            </a-form-item>
        </a-form>
    </a-modal>
</template>
<script setup>
import { computed, inject, onMounted, provide, ref } from "vue";
import { FullscreenOutlined } from "@ant-design/icons-vue";
import LinkCanvas from "./LinkCanvas.vue";
import { MoveStart } from "./MoveEvent";
const Box = ref();
const Board = ref();
const props = defineProps(["width", "height"]);
const emit = defineEmits(["MouseUpEvent"]);
const MoveCache = ref({ x: 0, y: 0, scale: 1 });
onMounted(() => {
    MoveCache.value.x = -(props.width - Box.value.clientWidth) / 2;
    MoveCache.value.y = -(props.height - Box.value.clientHeight) / 2;
});

const Wheel = (event) => {
    const Cache = {};

    Cache.x = (event.clientX - 51 - ((props.width * (1 - MoveCache.value.scale)) / 2 + MoveCache.value.x)) / MoveCache.value.scale;
    Cache.y = (event.clientY - ((props.height * (1 - MoveCache.value.scale)) / 2 + MoveCache.value.y)) / MoveCache.value.scale;

    var scale;
    if (event.wheelDelta < 0) {
        scale = MoveCache.value.scale - MoveCache.value.scale * 0.05;
    } else if (event.wheelDelta > 0) {
        scale = MoveCache.value.scale + MoveCache.value.scale * 0.05;
    }
    if (scale > 2) {
        scale = 2;
    } else if (scale < 0.5) {
        scale = 0.5;
    }
    MoveCache.value.scale = scale;

    const NewCache = {};

    NewCache.x = (event.clientX - 51 - ((props.width * (1 - MoveCache.value.scale)) / 2 + MoveCache.value.x)) / MoveCache.value.scale;
    NewCache.y = (event.clientY - ((props.height * (1 - MoveCache.value.scale)) / 2 + MoveCache.value.y)) / MoveCache.value.scale;

    MoveEnd(MoveCache.value.x, MoveCache.value.y);
};

const fullscreen = () => {
    MoveCache.value.scale = 1;
    MoveEnd(MoveCache.value.x, MoveCache.value.y);
};
const BoxLimit = computed(() => {
    return {
        xMin: -(props.width - props.width * MoveCache.value.scale) / 2,
        yMin: -(props.height - props.height * MoveCache.value.scale) / 2,
        xMax: -(props.width * MoveCache.value.scale + (props.width - props.width * MoveCache.value.scale) / 2 - Box.value.clientWidth),
        yMax: -(props.height * MoveCache.value.scale + (props.height - props.height * MoveCache.value.scale) / 2 - Box.value.clientHeight),
    };
});
const MoveEnd = (x, y) => {
    if (Box.value.clientWidth <= props.width * MoveCache.value.scale) {
        if (x > BoxLimit.value.xMin) {
            x = BoxLimit.value.xMin;
        } else if (x < BoxLimit.value.xMax) {
            x = BoxLimit.value.xMax;
        }
    } else {
        if (x < BoxLimit.value.xMin) {
            x = BoxLimit.value.xMin;
        } else if (x > BoxLimit.value.xMax) {
            x = BoxLimit.value.xMax;
        }
    }
    MoveCache.value.x = x;
    if (Box.value.clientHeight <= props.height * MoveCache.value.scale) {
        if (y > BoxLimit.value.yMin) {
            y = BoxLimit.value.yMin;
        } else if (y < BoxLimit.value.yMax) {
            y = BoxLimit.value.yMax;
        }
    } else {
        if (y < BoxLimit.value.yMin) {
            y = BoxLimit.value.yMin;
        } else if (y > BoxLimit.value.yMax) {
            y = BoxLimit.value.yMax;
        }
    }
    MoveCache.value.y = y;
};
const LinkCanvasView = ref();
const LinkCache = { x: 0, y: 0 };
const LinkEnd = (x, y) => {
    LinkCanvasView.value.SetEndPoint({ x, y });
    // LinkStatus.value = false;
};
const LinkRealEnd = (x, y) => {
    LinkCanvasView.value.SetEndPoint({ x, y });
    LinkStatus.value = false;
    LinkCanvasView.value.Clear();
};

const LinkStatus = inject("LinkStatus");
const Move = (event) => {
    if (LinkStatus.value) {
        LinkCache.x = (event.clientX - 51 - ((props.width * (1 - MoveCache.value.scale)) / 2 + MoveCache.value.x)) / MoveCache.value.scale;
        LinkCache.y = (event.clientY - ((props.height * (1 - MoveCache.value.scale)) / 2 + MoveCache.value.y)) / MoveCache.value.scale;
        LinkCanvasView.value.SetStartPoint(LinkCache);
        MoveStart(event, LinkCache, MoveCache.value.scale, LinkEnd, LinkRealEnd);
    } else {
        MoveStart(event, MoveCache.value, 1, MoveEnd, MoveEnd);
    }
};
const AddEvent = (event) => {
    if (event.target == Board.value) {
        emit("MouseUpEvent", event);
    }
};

provide("MoveEvent", Move);

const AddeventVisible = ref(false);
const AddObject = ref({
    key: "",
    type: "",
});

let AddEventCache = null;
provide("AddEvent", function (callback) {
    AddObject.value = {
        key: "",
        type: "",
    };
    AddeventVisible.value = true;
    AddEventCache = callback;
});
</script>
<style lang="less" scoped>
.Box {
    position: absolute;
    bottom: 20px;
    left: 50px;
    right: 0;
    top: 0;
    overflow: hidden;

    .Board {
        background-color: rgba(0, 0, 0, 0.1);
        background-image: url(../Assets/BG.png);
        // position: absolute;
        // top: 50%;
        // left: 50%;
    }

    .Status {
        position: fixed;
        height: 20px;
        bottom: 0;
        left: 50px;
        right: 0;
        background-color: bisque;
        border-top: 1px solid #aaa;
        line-height: 20px;
        .Zoom {
            padding: 0 16px;
            font-size: 12px;
        }
    }
}
.fullscreen {
    cursor: pointer;
}
</style>
